import { vnode, vnodeProps } from "./index.d";

/**判断组件是否需要更新 **只要是 props 发生改变了，那么这个 component 就需要更新** 
 * @param prevVNode 旧Vnode
 * @param nextVNode 新Vnode
 * @returns 是否需要更新的布尔值  
 */
export function shouldUpdateComponent(prevVNode: vnode, nextVNode: vnode) {
    /**旧props */
    const prevProps = prevVNode.props;
    /**新props */
    const nextProps = nextVNode.props;
    //   const emits = component!.emitsOptions; 

    // props 没有变化，那么不需要更新
    if (prevProps === nextProps) return false;
    // 如果之前没有 props，那么就需要看看现在有没有 props 了， 所以这里基于 nextProps 的值来决定是否更新
    if (!prevProps) return !!nextProps; //双叹号把变量转为布尔值
    // 之前有值，现在没值，那么肯定需要更新
    if (!nextProps) return true;

    // 以上都是比较明显的可以知道 props 是否是变化的， 在 hasPropsChanged 会做更细致的对比检测
    return hasPropsChanged(prevProps, nextProps);
}
/**进行更细致的新旧props对比，判断是否需要更新
 * @param prevProps 旧props
 * @param nextProps 新props
 * @returns 是否需要更新的布尔值
 */
function hasPropsChanged(prevProps: vnodeProps, nextProps: vnodeProps): boolean {
    // 依次对比每一个 props.key


    /**新props的key数组 */
    const nextKeys = Object.keys(nextProps);
    if (nextKeys.length !== Object.keys(prevProps).length) { // 提前对比一下 length ，length 不一致肯定是需要更新的
        return true;
    }

    // 只要现在的 prop 和之前的 prop 不一样那么就需要更新
    for (let i = 0; i < nextKeys.length; i++) {
        const key = nextKeys[i];
        if (nextProps[key] !== prevProps[key]) {
            return true;
        }
    }
    return false;
}